#include "ljsonc_find.h"
#include "ljsonc_type.h"

#include <string.h>

ljsonc_element **get_elements(const ljsonc_json *json)
{
    if (json) {
        return json->values;
    }
    else {
        return NULL;
    }
}

ljsonc_element *find_element(const ljsonc_json *json, const char *key)
{
    ljsonc_element *elem = NULL;

    for (int i = 0; i < json->size; ++i) {
        if (strcmp(key, json->values[i]->key) == 0) {
            elem = json->values[i];
            break;
        }
    }

    return elem;
}

ljsonc_element *find_next_element(const ljsonc_json *json, const ljsonc_element *elem)
{
    for (int i = 0; i < json->size - 1; ++i) {
        if (elem == json->values[i]) {
            return json->values[i+i];
        }
    }
    
    return NULL;
}

bool get_element_value(const ljsonc_element *elem, char mod, void *ret_value)
{
    bool b_ret = false;
    
    if (elem && elem->value) {
        switch (mod) {
            case 'd': {
                int *i = (int *)ret_value;
                
                if (elem->value->valuetype == CJSON_VALUE_INT) {
                    *i = elem->value->value.int_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            case 'f': {
                double *f = (double *)ret_value;
                
                if (elem->value->valuetype == CJSON_VALUE_DOUBLE) {
                    *f = elem->value->value.df_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            case 's': {
                char **str = (char **)ret_value;
                
                if (elem->value->valuetype == CJSON_VALUE_STRING) {
                    *str = elem->value->value.str_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            case 'j': {
                ljsonc_json **json = (ljsonc_json **)ret_value;
                
                if (elem->value->valuetype == CJSON_VALUE_JSON) {
                    *json = elem->value->value.json_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }                
            
            case 'a': {
                ljsonc_array **array = (ljsonc_array **)ret_value;
                
                if (elem->value->valuetype == CJSON_VALUE_ARRAY) {
                    *array = elem->value->value.array_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            default:
                b_ret = false;
                break;
        }
    }
    
    return b_ret;    
}

ljsonc_value **get_array_values(const ljsonc_array *array)
{
    if (array) {
        return array->values;
    }
    else {
        return NULL;
    }
}

ljsonc_value *get_array_value(const ljsonc_array *array, unsigned int index)
{
    if (array && array->size > index) {
        return array->values[index];
    }
    else {
        return NULL;
    }
}

bool get_value(const ljsonc_value *value, char mod, void *ret_value)
{
    bool b_ret = false;
    
    if (value) {
        switch (mod) {
            case 'd': {
                int *i = (int *)ret_value;
                
                if (value->valuetype == CJSON_VALUE_INT) {
                    *i = value->value.int_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            case 'f': {
                double *f = (double *)ret_value;
                
                if (value->valuetype == CJSON_VALUE_DOUBLE) {
                    *f = value->value.df_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            case 's': {
                char **str = (char **)ret_value;
                
                if (value->valuetype == CJSON_VALUE_STRING) {
                    *str = value->value.str_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            case 'j': {
                ljsonc_json **json = (ljsonc_json **)ret_value;
                
                if (value->valuetype == CJSON_VALUE_JSON) {
                    *json = value->value.json_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }                
            
            case 'a': {
                ljsonc_array **array = (ljsonc_array **)ret_value;
                
                if (value->valuetype == CJSON_VALUE_ARRAY) {
                    *array = value->value.array_value;
                    b_ret = true;
                }
                else {
                    b_ret = false;
                }
                break;
            }
                
            default:
                b_ret = false;
                break;
        }
    }
    
    return b_ret;    
}